home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / fax / src / port / linux / mkdepend < prev    next >
Text File  |  1994-08-01  |  6KB  |  234 lines

  1. #! /bin/sh
  2. #    $Header: /usr/people/sam/fax/port/linux/RCS/mkdepend,v 1.3 1994/02/28 14:28:13 sam Rel $
  3. #
  4. # FlexFAX Facsimile Software
  5. #
  6. # Copyright (c) 1990, 1991, 1992, 1993, 1994 Sam Leffler
  7. # Copyright (c) 1991, 1992, 1993, 1994 Silicon Graphics, Inc.
  8. # Permission to use, copy, modify, distribute, and sell this software and 
  9. # its documentation for any purpose is hereby granted without fee, provided
  10. # that (i) the above copyright notices and this permission notice appear in
  11. # all copies of the software and related documentation, and (ii) the names of
  12. # Sam Leffler and Silicon Graphics may not be used in any advertising or
  13. # publicity relating to the software without the specific, prior written
  14. # permission of Sam Leffler and Silicon Graphics.
  15. # THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  16. # EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  17. # WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  18. # IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  19. # ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  20. # OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  21. # WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
  22. # LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
  23. # OF THIS SOFTWARE.
  24. #
  25. # NAME
  26. #    mkdepend - compute header file dependencies
  27. # SYNOPSIS
  28. #    mkdepend [-c compiler] [-e sedprog] [-f force] [-ipr] [-s sentinel]
  29. #        depfile file ...
  30. # DESCRIPTION
  31. #    See mkdepend(1).
  32. #
  33. me=$0
  34. usage="usage: $me [-c compiler] [-e sedprog] [-f force] [-ipr]\n\t[-s sentinel] depfile [file ...]"
  35. depgen="gcc -M"
  36. incremental=no
  37. rawdepinput=no
  38.  
  39. #
  40. # Process options and arguments.  We put quotes around the edit (-e) arguments
  41. # and use eval "sed -e ..." later, to preserve spaces in the edit command.
  42. #
  43.  
  44. set -- "$@"
  45.  
  46. while [ $# -gt 0 ] ; do
  47.     case $1 in
  48.       -c)    depgen=$2; shift;;
  49.       -e)    sedprog="$sedprog -e '$2'"; shift;;
  50.       -f)    force="$force $2"; shift;;
  51.       -i)    incremental=yes;;
  52.       -p)    depgen=collapse pcount=$2 rawdepinput=yes; shift;;
  53.       -r)    depgen=cat rawdepinput=yes;;
  54.       -s)    sentinel=$2 ; shift;;
  55.       -*)    echo $usage; exit 2;;
  56.       *)    break;;
  57.     esac
  58.     shift
  59. done
  60.  
  61. if [ $# -eq 0 ] ; then
  62.     echo $usage; exit 2
  63. fi
  64.  
  65. newdepfile=$1
  66. depfiledir=`dirname $1`
  67. olddepfile=$depfiledir/#`basename $1`
  68. shift
  69.  
  70. #
  71. # A shell function to collapse dependencies of targets in subdirectories
  72. # on common rightsides.
  73. #
  74. collapse() {
  75.     sed -e 's@/\([^/:]*\): @/%\1: @' $* |
  76.     sort -t% +1 |
  77.     uniq |
  78.     awk -F: '
  79.     BEGIN {
  80.         total = '$pcount'
  81.     }
  82.     function flush(group, lastdir, dirname, count) {
  83.         for (dirname in group)
  84.             count++
  85.         if (count == total) {
  86.             print group[lastdir]
  87.         } else {
  88.             for (dirname in group)
  89.                 print dirname group[dirname]
  90.         }
  91.         for (dirname in group)
  92.             delete group[dirname]
  93.     }
  94.     {
  95.         percent = index($1, "%")
  96.         name = substr($1, percent + 1)
  97.         if (name != basename || $2 != rightside) {
  98.             flush(group, dirname)
  99.             basename = name
  100.             rightside = $2
  101.         }
  102.         dirname = substr($1, 1, percent - 1)
  103.         group[dirname] = basename ":" rightside
  104.     }
  105.     END {
  106.         flush(group, dirname)
  107.     }' |
  108.     sort
  109. }
  110.  
  111. #
  112. # An awk script to compress and pretty-print dependencies.
  113. #
  114. awkprog='
  115. BEGIN {
  116.     FS = ":"
  117.     INDENT = "\t"
  118.     INDENTSIZE = 8
  119.     MAXLINE = 72
  120.     MAXINDENTEDLINE = MAXLINE - INDENTSIZE - 1
  121. }
  122.  
  123. #
  124. # For each line of the form "target1 ... targetN: dependent", where the
  125. # spaces are literal blanks, do the following:
  126. #
  127. {
  128.     if ($1 != target) {
  129.         if (depline) print depline
  130.         target = $1
  131.         depline= $0 "'"$force"'"
  132.         lim = MAXLINE
  133.     } else {
  134.         if (length(depline) + length($2) > lim) {
  135.             print depline " \\"
  136.             depline = INDENT
  137.             lim = MAXINDENTEDLINE
  138.         }
  139.         depline = depline $2
  140.     }
  141. }
  142.  
  143. END {
  144.     if (depline) print depline 
  145. }'
  146.  
  147. #
  148. # Save the old file in case of problems.  Define some temporary files for
  149. # incremental make depend.  Clean up if interrupted.
  150. #
  151. olddeps=/tmp/olddeps.$$
  152. newdeps=/tmp/newdeps.$$
  153. tmpdeps=$depfiledir/tmpdeps.$$
  154. if test "$incremental" = yes; then
  155.     trapcmds="rm -f $olddeps $newdeps $tmpdeps;"
  156. fi
  157. if test -f "$newdepfile"; then
  158.     trapcmds="$trapcmds mv -f \\$olddepfile \\$newdepfile;"
  159.     ln $newdepfile $olddepfile
  160.     echo "# placeholder in case make includes me" > $tmpdeps
  161.     mv -f $tmpdeps $newdepfile
  162. fi
  163. trap "$trapcmds exit 0" 1 2 15
  164.  
  165. #
  166. # Remove any old dependencies from the file.
  167. #
  168. firstline="#$sentinel DO NOT DELETE THIS LINE -- make depend uses it"
  169. lastline="#$sentinel DO NOT DELETE THIS 2nd LINE -- make depend uses it"
  170.  
  171. if test -f "$olddepfile"; then
  172.     sed -e "/^$firstline/,/^$lastline/d" $olddepfile
  173. fi > $newdepfile
  174.  
  175. #
  176. # Delimit the beginning of the dependencies.  Save the old dependencies
  177. # in incremental mode.
  178. #
  179. echo $firstline >> $newdepfile
  180. if test $incremental = yes; then
  181.     #
  182.     # XXX Workaround for this sed bug: 1,/pat/d deletes 1,$ if line 1
  183.     # XXX and only line 1 matches pat.
  184.     #
  185.     (echo '# food for sed bug to eat'; cat $olddepfile 2> /dev/null) |
  186.         sed -e "1,/^$firstline/d" -e "/^$lastline/"',$d' > $olddeps
  187.  
  188.     #
  189.     # Compose an awk program that deletes pretty-printed dependencies
  190.     # from $olddeps that involve basenames of objects (in the raw input)
  191.     # or sources (arguments) whose dependencies are being updated.
  192.     #
  193.     awkinc='/^[^     ]/ { deleting = 0; }'
  194.     if test $rawdepinput = yes; then
  195.         cat $* > $newdeps
  196.         for f in `sed -e 's@^\([^:/]*\)\.[^:/]*: .*@\1@' \
  197.                   -e 's@^[^:]*/\([^:/]*\)\.[^:/]*: .*@\1@' \
  198.                   $newdeps |
  199.               sort -u`; do
  200.             list="$list $f"
  201.         done
  202.         set -- $newdeps
  203.     else
  204.         for f in $*; do
  205.             list="$list `expr ./$f : '.*/\(.*\)\..*'`"
  206.         done
  207.     fi
  208.     for f in $list; do
  209.         awkinc="$awkinc /^$f\./ || /^[^     :]*\/$f\./ { deleting = 1; }"
  210.     done
  211.     awkinc="$awkinc { if (!deleting) print \$0; }"
  212.     awk "$awkinc" $olddeps >> $newdepfile
  213.     rm -f $olddeps
  214. fi
  215.  
  216. #
  217. # Process source files - the sed commands and their functions are: 
  218. #    s:[^\./][^\./]*/\.\./::g    rewrite "dir/../path" to be "path"
  219. #    s:\([/ ]\)\./:\1:g        rewrite " ./path" to be " path" and
  220. #                    remove the "./" from  ".././h/x.h"
  221. #
  222. $depgen $* |
  223.     eval "sed \
  224.     -e :loop -e 's:[^\./][^\./]*/\.\./::g' -e tloop \
  225.     -e 's:\([/ ]\)\./:\1:g' \
  226.     $sedprog" |
  227.     awk "$awkprog" >> $newdepfile
  228.  
  229. echo $lastline >> $newdepfile
  230. rm -f $olddepfile $newdeps
  231.